#多态————多种形态与java不一样
#python天生支持多态（鸭子类型），只关注对象有没有该方法，而不关心它是什么数据类型
# class Email():
#     def send(self):
#         print("发邮件")
# class Message():
#     def send(self):
#         print("发短信")
# def func(arg):
#     v1=arg.send()
#     print(v1)
# v1=Email()
# func(v1)
# v2=Message()
# func(v2)
import xml.sax


#封装：将方法封装到类中或者将数据类型封装到对象中，便于以后使用
#继承：将类中的公共方法提取到类中去实现
#多态：Python默认支持多态（这种方式称之为鸭子类型）。

#再看数据类型
#每一种数据类型就是一个类,所有类都会默认继承object(python3)
#python2 :继承obj--新式类，非--经典类


#多态
# class Animal(object):
# #     def animal_sound(self):
# #         pass
# # class Dog(Animal):
# #     def animal_sound(self):
# #         print("旺旺")
# # class Cat(Animal):
# #     def animal_sound(self):
# #         print("喵喵")
# # def Animal_speak(animal):
# #     animal.animal_sound()
# # myDog = Dog()
# # myCat = Cat()
# # Animal_speak(myCat)
# # Animal_speak(myDog)

#面向对象进阶
#成员：变量、方法、属性
#      变量：
#           实例变量：属于对象，每个对象各自维护自己的数据
#           类变量：属于类，可以被所有对象共享，一般用于给对象提供公共数据（类似于全局变量）
# class Person(object):
#     country="中国"  #类变量
#     def __init__(self,name,age):
#         self.name=name #实例变量
#         self.age=age
#     def show(self):
#         # print(f'{self.name} :{self.age},{Person.country}')
#         print(f'{self.name} :{self.age},{self.country}')
# boy=Person("小峰",23)
# boy.show()
# boy.country="日本"
# boy.show()

#      方法：
#           绑定方法：默认都有一个self参数，由对象进行调用（此时self就等于调用方法的这个对象）【对象&类均可调用】
#           类方法：默认有一个cls参数，用类或对象都可以调用（此时cls就等于调用这个方法的类）【对象&类均可调用】
#           静态方法：无默认参数，用类和对象都可以调用【对象&类均可调用】
# class Foo(object):
#     def __init__(self,name,age):
#         self.name = name
#         self.age = age
#     def f1(self):
#         print("绑定方法",self.name,self.age)
#     @classmethod
#     def f2(cls):
#         print("类方法",cls)
#     @staticmethod
#     def f3():
#         print("静态方法")
#绑定方法 ---用到self
# obj=Foo("小峰",23)
# obj.f1()  --主流
# Foo.f1(obj)
#类方法  --用到类
# Foo.f2() #cls就是当前调用方法的 类  --主流
# obj.f2() #cls就是当前调用方法对象的 类
#静态方法 --简单的处理逻辑
# Foo.f3()  #--主流
# obj.f3()

#      属性：其实就是由绑定方法和特殊的装饰器组合创造出来的，让我们以后再调用方法的时候可以不加括号
#方便读别人的代码以及源码
# class Foo(object):
#     def __init__(self,name):
#         self.name = name
#     def f1(self):
#         return 123
#     @property  #属性
    # def f2(self):
    #     return 456
    # @property
    # def x(self):
    #     pass
    # @x.setter  #基于装饰器
    # def x(self,value):
    #     pass
    # @x.deleter #基于装饰器
    # def x(self):
    #     pass


# obj=Foo('Bob')
# v1=obj.f1()
# print(v1)
# v2=obj.f2
# print(v2)
# obj=Foo()
# obj.x
# obj.x=123
# del obj.x

#基于变量
# class C(object):
#     def getx(self):
#         pass
#     def setx(self,value):
#         pass
#     def delx(self):
#         pass
#     x=property(getx,setx,delx,"I am the x's property") #最后面的为注释
# obj=C()
# obj.x #自动执行最左边的方法
# obj.x=112  #自动执行中间的方法
# del obj.x  #自动执行最右边的方法

#由于属性和实例变量的调用方式一样，所以在编写的时候需要注意：属性名称不要与实例变量重名
#一旦重名，就会报错，也会出现递归的层级错误






